// 第四步：实现依赖收集者 Dep (相当于订阅管理者)
// 作用：维护一个数组用于收集依赖并且发布消息，在响应式属性的 getter 触发时收集依赖，在 setter 触发时通知所有依赖(订阅者)，触发相应的变更逻辑
export class Dep {
  constructor() {
    // 初始化一个依赖收集器的数组
    this.subs = []
  }
  
  // 把依赖添加到依赖收集器
  addSub(sub) {
    this.subs.push(sub)
  }

  // 把依赖从依赖收集器中删除，这里用不上，应该是用于 vm.$delete
  removeSub(sub) {
    remove(this.subs, sub)
  }

  // 收集依赖，从全局的 window.target 中取收集依赖
  depend() {
    if (window.target) this.addSub(window.target)
  }

  // 发布消息，通知所有依赖触发相应的变更
  notify() {
    // 浅拷贝依赖收集器
    const copySubs = this.subs.slice()
    // 遍历执行依赖的变更逻辑
    copySubs.forEach(item => item.update())
  }
}

// 从数组删除某个指定的项：先找到数组中该元素对应下标，然后使用 splice(index, 1) 去移除
function remove(arr, item) {
  const index = arr.indexOf(item)
  if (index !== -1) arr.splice(index, 1)
}
